package yt.demo.appcoresystem.impl;

import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import yt.demo.appcommonbean.exception.LogicException;
import yt.demo.appcommondb.base.BaseService;
import yt.demo.appcommondb.tools.ListConverter;
import yt.demo.appcommondb.vo.ConditionVO;
import yt.demo.appcoresystem.dto.MenuTreeDTO;
import yt.demo.appcoresystem.dto.Pair;
import yt.demo.appcoresystem.dto.RoleMenuDTO;
import yt.demo.appcoresystem.entity.SystemMenu;
import yt.demo.appcoresystem.entity.SystemUser;
import yt.demo.appcoresystem.mapper.SystemMenuMapper;
import yt.demo.appcoresystem.service.ISystemMenuService;
import yt.demo.appcoresystem.service.ISystemRoleMenuService;
import yt.demo.appcoresystem.service.ISystemUserRoleService;
import yt.demo.appcoresystem.vo.ButtonVo;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SystemMenuService extends BaseService<SystemMenu, SystemMenuMapper> implements ISystemMenuService {

    ISystemRoleMenuService roleMenuService;
    ISystemUserRoleService userRoleService;

    @Autowired
    public SystemMenuService(SystemMenuMapper mapper, ISystemRoleMenuService roleMenuService, ISystemUserRoleService userRoleService) {
        super(mapper, SystemMenu.class);
        this.roleMenuService = roleMenuService;
        this.userRoleService = userRoleService;
    }

    @Override
    protected List<ConditionVO<SystemMenu, ?>> whereConditions(SystemMenu params) {
        return List.of();
    }

    public List<MenuTreeDTO> getMenu() {
        List<ConditionVO<SystemMenu, ?>> conditions = new ArrayList<>();
        SystemUser userInfo = AuthService.getUserInfo();
        if (ObjectUtil.isNotNull(userInfo.getId())) {
            List<Long> menuIds = getUserMenuIds(userInfo.getId());
            if (menuIds.isEmpty()){
                throw new LogicException("无权限");
            }
            if (!menuIds.contains(-1L)){
                conditions.add(ConditionVO.createCondition(SystemMenu::getId, "in", menuIds));
            }
        }
        List<SystemMenu> list = getList(null, w -> {
            w.orderByDesc("sort");
        }, conditions);

        Pair<List<SystemMenu>, List<ButtonVo>> result = dustingMenu(list);
        List<SystemMenu> menus = result.getFirst();  // 获取菜单
        List<ButtonVo> buttons = result.getSecond();  // 获取按钮
        return toTree(menus, buttons, 0L);
    }

    private List<Long> getUserMenuIds(Long userId) {
       List<Long> roleIds  = userRoleService.getUserRoleIds(userId);
        if (roleIds.contains(1L)) {
            return List.of(-1L);
       }
       return roleMenuService.getRoleMenuIds(roleIds);
    }

    public List<RoleMenuDTO> getRoleMenu() {
        return ListConverter.convertList(executeQuery(w -> {
            w.orderByDesc("sort");
        }, null), RoleMenuDTO.class);
    }

    //树形
    public static List<MenuTreeDTO> toTree(List<SystemMenu> data, List<ButtonVo> baths, Long parentId) {
        List<MenuTreeDTO> tree = new ArrayList<>();
        for (SystemMenu menu : data) {
            if (Objects.equals(menu.getParentId(), parentId)) {
                MenuTreeDTO menuTreeDTO = new MenuTreeDTO();
                menuTreeDTO.setPath(menu.getComponent());
                menuTreeDTO.setName(menu.getCode());
                // 设置 meta 字段
                MenuTreeDTO.Meta meta = new MenuTreeDTO.Meta();
                meta.setTitle(menu.getName());
                meta.setIcon(menu.getIcon());
                meta.setRoles(List.of("admin"));  // 固定角色

                meta.setAuths(matchingBtn(menu.getId(), baths));  // 获取该菜单的按钮权限
                menuTreeDTO.setMeta(meta);

                // 递归处理子菜单
                List<MenuTreeDTO> children = toTree(data, baths, menu.getId());
                if (!children.isEmpty()) {
                    menuTreeDTO.setChildren(children);
                } else {
                    // 如果没有子节点，设置为空列表而不是 null
                    menuTreeDTO.setChildren(new ArrayList<>());
                }
                tree.add(menuTreeDTO);
            }
        }
        return tree;
    }

    public List<String> getRoleRoutes(List<Long> roleIds) {
        List<Long> menuIds = roleMenuService.getRoleMenuIds(roleIds);
        if (menuIds.isEmpty()) {
            return new ArrayList<>();
        }
        List<SystemMenu> list = getList(null, w -> {
            w.in(SystemMenu::getId, menuIds);
        }, null);
        return list.stream().map(SystemMenu::getRoute).filter(route -> route != null && !route.isEmpty())
                .distinct().collect(Collectors.toList());
    }

    public List<String> getUserRoleIdsRoutes(Long userId) {
        List<Long> roleIds = userRoleService.getUserRoleIds(userId);
        if (roleIds == null || roleIds.isEmpty()) {
            return List.of();
        }
        if (roleIds.contains(1L)) {
            return List.of("*");
        }
        return getRoleRoutes(roleIds);
    }

    public static Pair<List<SystemMenu>, List<ButtonVo>> dustingMenu(List<SystemMenu> list) {
        List<SystemMenu> menus = list.stream()
                .filter(item -> item.getMenuType() != 3)
                .toList();
        List<ButtonVo> baths = list.stream()
                .filter(item -> item.getMenuType() == 3)
                .map(item -> new ButtonVo(item.getParentId(), item.getCode()))
                .toList();
        return new Pair<>(menus, baths);
    }

    public static List<String> matchingBtn(Long id, List<ButtonVo> data) {
        return data.stream()
                .filter(button -> Objects.equals(button.getParentId(), id))  // 过滤出 parentId 匹配的按钮
                .map(ButtonVo::getCode)                          // 提取出 code 字段
                .collect(Collectors.toList());                  // 收集到一个列表中
    }
}
